import { Composer, useI18n, VueI18n } from 'vue-i18n';
import { ILocale, ILocalType } from '@/store/types';
import { i18n } from '@/locales/setupI18n';
import { reactive, Ref, toRefs, toRef, watch, ToRefs, ref, shallowReactive } from 'vue';
import { useAppSettingStoreWithOut } from '@/store/module/useAppSettingStore';
import _default from 'element-plus/lib/locale/lang/zh-cn';
import { useNProgress } from '@vueuse/integrations/useNProgress';
import { setLocale as setDynamicFormLocale } from '@vee-validate/i18n';
const elementLocaleEnum = {
  [ILocale.ZH_CN]: () => import('element-plus/lib/locale/lang/zh-cn'),
  [ILocale.EN]: () => import('element-plus/lib/locale/lang/en'),
};

export const setHtmlLanguage = (locale: ILocalType) => {
  const html = document.documentElement;
  html.lang = locale;
};

/**
 * 使用非响应式全局本地化
 */
export const useLocale = (): any => {
  return i18n.global;
};

//使用响应式全局I18n
export const useVueI18n = (): ToRefs<
  Composer<unknown, unknown, unknown, unknown, never, unknown>
> => {
  return toRefs(reactive(useI18n({ useScope: 'global' }))) as unknown as ToRefs<
    Composer<unknown, unknown, unknown, unknown, never, unknown>
  >;
};

/**
 * 设置当前本地化语言
 * @param locale 本地化语言标识
 */
export const setLocale = async (locale: ILocalType) => {
  const global = useLocale();
  setHtmlLanguage(locale);
  //设置动态表单本地化
  setDynamicFormLocale(locale);
  if (global?.availableLocales.includes(locale)) {
    global.locale = locale;
    return;
  }
  //使用顶部进度条表示加载语言包的进度
  const { start, done } = useNProgress();
  start();
  const defaultLocale = await import(`./lang/${locale}.ts`);
  const message = defaultLocale.default;
  global.setLocaleMessage(locale, message);
  global!.locale = locale;
  done();
};

/**
 * 使用element本地化，按需加载
 * 按需加载对messagebox等挂载在app外层的组件貌似无用
 */
export const useElementLocale = (): Ref<typeof _default> => {
  const appSettingStore = useAppSettingStoreWithOut();
  const locale = ref<typeof _default>(null!) as Ref<typeof _default>;
  watch(
    () => appSettingStore.configLocal.locale,
    async (newValue) => {
      const elDefaultLocale = await elementLocaleEnum[newValue]();
      // @ts-ignore
      locale.value = shallowReactive(elDefaultLocale.default as typeof _default);
    },
    { immediate: true }
  );
  return locale;
};
